package com.da.javatest.thread.juc.base;

/**
 * @author JokerDa.
 * @date 2021/7/7 15:14
 * Description:
 */
public class ThreadDemo1 {
    private int number = 0;

    /**
     * 用IF会造成虚假唤醒的情况，需要改成while，因为wait()唤醒的时候，从哪里醒来就会从哪里开始执行
     */
    public synchronized void incr() throws InterruptedException {
        //if (number != 0) {
        //    this.wait();
        //}

        while (number != 0) {
            this.wait();
        }

        // 如果number为0则+1
        number++;
        System.out.println(Thread.currentThread().getName() + "::" + number);

        // 通知其他线程
        this.notifyAll();
    }

    public synchronized void decr() throws InterruptedException {
        while (number != 1) {
            this.wait();
        }

        // 如果number为0则-1
        number--;
        System.out.println(Thread.currentThread().getName() + "::" + number);

        // 通知其他线程
        this.notifyAll();
    }

    public static void main(String[] args) {
        ThreadDemo1 share = new ThreadDemo1();

        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    share.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "AA").start();

        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    share.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "BB").start();

        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    share.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "CC").start();

        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    share.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "DD").start();
    }
}



